package MIDI.Control_Events is

   type Types is (
      Note_Off, 
      Note_On, 
      Key_After_Touch, 
      Controller_Change,
      Program_Change,
      Channel_After_Touch,
      Pitch_Wheel_Change
      );

   -- 8x
   type Note_Off_Event is record
      Note     : Uint8_t;
      Velocity : Uint8_t;
   end record;

   -- 9x
   type Note_On_Event is record
      Note     : Uint8_t range 0 .. 127;
      Velocity : Uint8_t range 0 .. 127;
   end record;

   -- ax
   type Key_After_Touch_Event is record
      Note     : Uint8_t;
      Pressure : Uint8_t;
   end record;

   -- bx
   type Controller_Change_Event is record
      Controller : Uint8_t range 0 .. 127;
      Value      : Uint8_t range 0 .. 127;
   end record;

   -- cx
   type Program_Change_Event is record
      Patch    : Uint8_t range 0 .. 127;
   end record;

   -- dx
   type Channel_After_Touch_Event is record
      Pressure : Uint8_t range 0 .. 127;
   end record;

   -- ex
   type Pitch_Wheel_Change_Event is record
      LSB      : Uint8_t range 0 .. 127;
      MSB      : Uint8_t range 0 .. 127;
   end record;

   function To_Pitch_Value (P : Pitch_Wheel_Change_Event) return Uint16_be;

   type Control_Event (Name : Types; Channel : Uint8_t) is record
      case Name is
         when Note_Off            => As_Note_Off            : Note_Off_Event;
         when Note_On             => As_Note_On             : Note_On_Event;
         when Key_After_Touch     => As_Key_After_Touch     : Key_After_Touch_Event;
         when Controller_Change   => As_Controller_Change   : Controller_Change_Event;
         when Program_Change      => As_Program_Change      : Program_Change_Event;
         when Channel_After_Touch => As_Channel_After_Touch : Channel_After_Touch_Event;
         when Pitch_Wheel_Change  => As_Pitch_Wheel_Change  : Pitch_Wheel_Change_Event;
      end case;
   end record
   with Read => Read, Write => Write;

private
   procedure Read (
      From : not null access Root_Stream_Type'Class;
      C    : out Control_Event 
      );

   procedure Write (
      From : not null access Root_Stream_Type'Class;
      C    : Control_Event 
      );

end MIDI.Control_Events;
